package interview.aba;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

public class ABASolution {

    static AtomicInteger atomicInteger = new AtomicInteger(100);

    static AtomicStampedReference atomicStampedReference = new AtomicStampedReference(100,1);

    public static void main(String[] args) {
        System.out.println("==============ABA问题的产生=======================");
        new Thread(()->{
            boolean isOk=atomicInteger.compareAndSet(100,101);
            System.out.println(Thread.currentThread().getName()+" isOK:"+isOk+" 当前值："+atomicInteger.get());
            isOk=atomicInteger.compareAndSet(101,100);
            System.out.println(Thread.currentThread().getName()+" isOK:"+isOk+" 当前值："+atomicInteger.get());
        },"T1").start();

        new Thread(()->{
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            boolean isOk = atomicInteger.compareAndSet(100,101);
            System.out.println(Thread.currentThread().getName()+" isOK:"+isOk+" 当前值："+atomicInteger.get());
        },"T2").start();


        sleep(1000);
        System.out.println("==============ABA问题的解决=======================");

        new Thread(()->{
             int stamp = atomicStampedReference.getStamp();
             System.out.println(Thread.currentThread().getName()+" 当前值:"+atomicStampedReference.getReference()+" 当前时间戳:"+atomicStampedReference.getStamp());

             sleep(1000);
             boolean isOK = atomicStampedReference.compareAndSet(100,101,stamp,stamp+1);
             System.out.println(Thread.currentThread().getName()+" isOK:"+isOK+" 当前值："+atomicStampedReference.getReference()+" 当前时间戳:"+atomicStampedReference.getStamp());

            sleep(1000);
            atomicStampedReference.compareAndSet(101,100,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1);
            System.out.println(Thread.currentThread().getName()+" isOK:"+isOK+" 当前值："+atomicStampedReference.getReference()+" 当前时间戳:"+atomicStampedReference.getStamp());


        },"T3").start();


        new Thread(()->{
            int stamp = atomicStampedReference.getStamp();
            System.out.println(Thread.currentThread().getName()+" 当前值:"+atomicStampedReference.getReference()+" 当前时间戳:"+atomicStampedReference.getStamp());
            sleep(3000);
            boolean isOK = atomicStampedReference.compareAndSet(100,101,stamp,stamp+1);
            System.out.println(Thread.currentThread().getName()+" isOK:"+isOK+" 当前值："+atomicStampedReference.getReference()+" 当前时间戳:"+atomicStampedReference.getStamp());
        },"T4").start();


    }

    public static void sleep(long second){

        try {
            Thread.sleep(second);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
